﻿using DG.Tweening;
using GameProtocol.Protocol;
using Google.Protobuf;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using UnityEngine.Events;

namespace GameLogic
{
    public class NetServer
    {
        public static float TimeoutMax = 7;
        protected ConcurrentDictionary<string, ClientHandle> m_ClientHandleMap = new ConcurrentDictionary<string, ClientHandle>();
        protected int m_ReceivePort = -1;
        protected Dictionary<GameProtocol.Protocol.CSMsgId, UnityEvent<IPEndPoint, byte[]>> m_ReceiveEvents = new Dictionary<GameProtocol.Protocol.CSMsgId, UnityEvent<IPEndPoint, byte[]>>();
        protected int m_SendPort = -1;
        public virtual void Init(int receivePort = 24567, int sendPort = 24568)
        {
            m_ReceivePort = receivePort;
            m_SendPort = sendPort;
            AddListener(CSMsgId.HeartJumpRqr, OnHeartJumRqr);
        }
        public virtual void Disconnect()
        {
        }
        public virtual void Clear()
        {
            
        }
        public UnityAction<IPEndPoint, byte[]> AddListener(GameProtocol.Protocol.CSMsgId type, UnityAction<IPEndPoint, byte[]> action)
        {
            if (!m_ReceiveEvents.ContainsKey(type))
                m_ReceiveEvents.Add(type, new UnityEvent<IPEndPoint, byte[]>());
            m_ReceiveEvents[type].AddListener(action);
            return action;
        }
        public void RemoveListener(GameProtocol.Protocol.CSMsgId type, UnityAction<IPEndPoint, byte[]> action)
        {
            if (!m_ReceiveEvents.ContainsKey(type))
                return;
            m_ReceiveEvents[type].RemoveListener(action);
        }
        public virtual void Update()
        {
            foreach(var i in m_ClientHandleMap)
            {
                i.Value.Update();
            }
        }
        protected virtual void OnReceived(IPEndPoint ep, byte[] data, int curOffset, int length)
        {
        }
        protected byte[] m_SendDataBuffer = new byte[1024];
        public virtual void Send(GameProtocol.Protocol.CSMsgId id, IPEndPoint ep, byte[] data)
        {
        }
        protected virtual void Send(IPEndPoint endPoint, byte[] data, int length)
        {
        }
        protected virtual async void OnClientTimeout(ClientHandle clientHand)
        {
            await Task.Yield();
            m_ClientHandleMap.TryRemove(clientHand.IP, out var j );
        }
        void OnHeartJumRqr(IPEndPoint ep, byte[] data)
        {
            HeartJumpRspData heartJumpRspData = new HeartJumpRspData();
            Send(CSMsgId.HeartJumpRsp, ep, heartJumpRspData.ToByteArray());

            var ip = ep.Address.ToString();
            m_ClientHandleMap?[ip].RecountTimeout();
        }
        protected void OnHandshakeSuccess(string ip)
        {
            if (!m_ClientHandleMap.ContainsKey(ip))
                return;
        }
    }
}
